package com.social.controller;

import com.alibaba.fastjson.JSON;
import com.social.pojo.*;
import com.social.service.*;
import com.social.util.JsonUtil;
import com.social.util.Md5Utils;
import com.social.util.PageUtil;
import com.social.util.StatusUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.aspectj.apache.bcel.classfile.CodeException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.social.util.ImageCodeUtil.createImage;
import static com.social.util.ImageCodeUtil.getSecurityCode;
import static com.social.util.SendPhoneUtil.getPhoneMsg;
import static com.social.util.SendPhoneUtil.getRandom;

/**
 * 用户操作
 */
@Controller
@RequestMapping("User")
public class UserController {
    /**
     * User  业务层
     */
    @Resource
    private UserService userService;
    /**
     * UserRole  业务层
     */
    @Autowired
    private UserRoleService userRoleService;
    /**
     * RolePermission  业务层
     */
    @Autowired
    private RolePermissionService rolePermissionService;
    /**
     * UserPost  业务层
     */
    @Autowired
    private UserPostService userPostService;

    /**
     * @param username 登录用户名
     * @param password 登录密码
     * @param session  session作用域
     * @param ImgCode  验证码
     * @return 错误信息
     */
    @RequestMapping(value = "login", produces = "text/application;charset=utf-8")
    @ResponseBody
    public String login(String username, String password, HttpSession session, String ImgCode) {
        JsonUtil jsonUtil = new JsonUtil();
        try {
            //获取主体对象
            Subject subject = SecurityUtils.getSubject();
            //封装token
            AuthenticationToken authenticationToken = new UsernamePasswordToken(username, password);
            //获取验证码
            String code = (String) session.getAttribute("code");
            //判断验证码是否正确
            if (!code.equals(ImgCode)) {
                throw new RuntimeException();
            }
            //查询用户信息
            User user = userService.selectByUsername(username);
            if (user.getState() == 0) {
                jsonUtil.setCode("账户已被关闭请联系管理员...");
                return JSON.toJSONString(jsonUtil.getCode());
            }
            //认证
            subject.login(authenticationToken);
            //存入用户信息
            session.getServletContext().setAttribute("user", user);
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            jsonUtil.setCode("账户不存在...");
            return JSON.toJSONString(jsonUtil.getCode());
        } catch (IncorrectCredentialsException e) {
            jsonUtil.setCode("密码错误...");
            return JSON.toJSONString(jsonUtil.getCode());
        } catch (RuntimeException e) {
            jsonUtil.setCode("验证码错误...");
            return JSON.toJSONString(jsonUtil.getCode());
        }
        return JSON.toJSONString("true");
    }

    /**
     * 登出
     *
     * @param session 作用域
     * @return 页面
     */
    @RequestMapping("logout")
    public String logout(HttpSession session) {
        //删除用户信息
        session.removeAttribute("user");
        return "redirect:/login.jsp";
    }

    /**
     * 验证码
     *
     * @param session  作用域
     * @param response 响应
     * @throws Exception 输出异常
     */
    @RequestMapping("imgCode")
    public void code(HttpSession session, HttpServletResponse response) throws Exception {
        //获得随机字符
        String securityCode = getSecurityCode();
        //将随机验证码字符存入session
        session.setAttribute("code", securityCode);
        //生成图片
        BufferedImage image = createImage(securityCode);
        //输出流
        OutputStream outputStream = response.getOutputStream();
        //将生成的验证码输出到浏览器
        ImageIO.write(image, "png", outputStream);
    }


    /**
     * 发送验证码的方法
     *
     * @param session 作用域
     * @param phone   电话号
     * @return 错误或正确信息
     */
    @RequestMapping(value = "code", produces = "text/application;charset=utf-8")
    @ResponseBody
    public String Code(HttpSession session, String phone) {
        //获取随机验证码
        String randomCode = getRandom(6);
        System.out.println("验证码:" + randomCode);
        //调用方法
        String message = getPhoneMsg(phone, randomCode);
        JsonUtil jsonUtil = new JsonUtil();
        if (message != null) {
            //存入手机验证码状态
            jsonUtil.setCode(message);
            //存入验证码
            session.setAttribute("phoneCode", randomCode);
            return JSON.toJSONString(jsonUtil.getCode());
        } else {
            jsonUtil.setCode("验证码发送失败请检查网络...");
            return JSON.toJSONString(jsonUtil.getCode());
        }
    }

    /**
     * 注册功能
     *
     * @param username  用户名
     * @param password  密码
     * @param phoneCode 电话验证码
     * @param session   作用域
     * @param ImgCode   字符验证码
     * @return 添加状态
     */
    @RequestMapping(value = "insert", produces = "text/application;charset=utf-8")
    @ResponseBody
    public String insert(String username,String realName, String password, String phoneCode, HttpSession session, String ImgCode) {
        JsonUtil jsonUtil = new JsonUtil();
        //查询有没有用户名重复
        User user = userService.selectByUsername(username);
        //获取手机号验证码
        String phoneCodes = (String) session.getAttribute("phoneCode");
        //获取验证码
        String code = (String) session.getAttribute("code");
        //判断账户是否存在
        if (user != null) {
            //存在返回错误信息跳转
            jsonUtil.setCode("用户名已存在...");
            return JSON.toJSONString(jsonUtil.getCode());
        } else if (!code.equals(ImgCode)) {
            //判断验证码是否正确
            jsonUtil.setCode("验证码错误...");
            return JSON.toJSONString(jsonUtil.getCode());
        } else if (!phoneCode.equals(phoneCodes)) {
            //存在返回错误信息跳转
            jsonUtil.setCode("手机验证码错误...");
            return JSON.toJSONString(jsonUtil.getCode());
        } else {
            //md5加密
            String md5Pwd = Md5Utils.getMd5Code(password);
            //创建对象
            User users = new User();
            users.setUsername(username);
            users.setRealName(realName);
            users.setPassword(md5Pwd);
            users.setState(1);
            //成功插入信息
            userService.insertSelective(users);
            //查询新添加的数据
            User user2 = userService.queryByUsername(username);
            //默认角色 科室操作人员
            UserRole userRole = new UserRole(user2.getId(), 3);
            //用户与角色中间表添加
            userRoleService.insertSelective(userRole);
            User user3 = userService.selectByUsername(username);
            //获得角色集合
            ArrayList<Role> roles = user3.getRoles();
            for (Role role : roles) {
                //角色对应权限
                RolePermissionKey rolePermissionKey = new RolePermissionKey(role.getId(), 3);
                RolePermissionKey rolePermission = rolePermissionService.selectByRoleId(role.getId());
                if (rolePermission == null) {
                    rolePermissionService.insertSelective(rolePermissionKey);
                } else {
                    rolePermissionService.updateByRoleId(rolePermissionKey);
                }
            }
            session.setAttribute("userName", username);
            return JSON.toJSONString("true");
        }
    }

    /**
     * 添加用户功能
     *
     * @param username     用户名
     * @param realName     姓名
     * @param password     密码
     * @param departmentId 岗位id
     * @return 添加状态
     */
    @RequestMapping(value = "userInsert", produces = "text/application;charset=utf-8")
    @ResponseBody
    public String userInsert(String username, String realName, String password, Integer departmentId) {
        //md5加密
        String md5Pwd = Md5Utils.getMd5Code(password);
        //创建对象
        User user = new User(null, username, md5Pwd, realName, String.valueOf(departmentId), 1, null, null);
        User users = userService.queryByUsername(username);
        int status = 0;
        if (users != null) {
            return JSON.toJSONString("用户名重复");
        } else {
            //添加用户方法
            status = userService.insertSelective(user);
            User user2 = userService.queryByUsername(username);
            UserPostKey userPostKey = new UserPostKey(user2.getId(), departmentId);
            userPostService.insertSelective(userPostKey);
            UserRole userRole = new UserRole(user2.getId(), 3);
            userRoleService.insertSelective(userRole);
        }
        JsonUtil jsonUtil = new JsonUtil();
        //设置状态
        Boolean restates = jsonUtil.getRestates(status);
        return JSON.toJSONString(restates);
    }

    /**
     * 查询所有用户
     *
     * @param session 作用域
     * @param page    当前页
     * @param pageNum 每页条数
     * @return 页面
     */
    @RequestMapping("selectByUser")
    public String selectByUser(HttpSession session, Integer page, Integer pageNum, Integer status) {
        List<User> users = userService.selectByUser(page, pageNum);
        Integer count = userService.selectCount();
        //分页方法
        Map<String, Integer> util = PageUtil.page(pageNum, page, count);
        Integer pages = util.get("page");
        Integer remaining_pages = util.get("remaining_pages");
        Integer counts = util.get("count");
        Map<String, Object> map = new HashMap<String, Object>();
        //存入分页数据
        map.put("num", remaining_pages);
        map.put("page", pages);
        map.put("count", counts);
        //存入map集合
        session.setAttribute("map", map);
        session.setAttribute("users", users);
        return StatusUtil.statusYe(status);
    }


    /**
     * 模糊查询所有用户
     *
     * @param session      作用域
     * @param realName     姓名
     * @param departmentId 部门id
     * @param page         当前页
     * @param pageNum      每页条数
     * @param status       状态
     * @return 页面
     */
    @RequestMapping("selectByUserLike")
    public String selectByUserLike(HttpSession session, String realName, String departmentId, Integer page, Integer pageNum, Integer status) {
        List<User> users = userService.selectByUserLike("%" + realName + "%", departmentId, page, pageNum);
        Integer count = userService.selectCountLike("%" + realName + "%", departmentId);
        //分页方法
        Map<String, Integer> util = PageUtil.page(pageNum, page, count);
        Integer pages = util.get("page");
        Integer remaining_pages = util.get("remaining_pages");
        Integer counts = util.get("count");
        Map<String, Object> map = new HashMap<String, Object>();
        //存入分页数据
        map.put("nums", remaining_pages);
        map.put("pages", pages);
        map.put("counts", counts);
        //存入map集合
        session.setAttribute("map", map);
        session.setAttribute("users", users);
        session.setAttribute("realName", realName);
        if (departmentId != null || departmentId != "") {
            session.setAttribute("departmentId", departmentId);
        }
        if (status == null) status = 13;
        return StatusUtil.statusYe(status);
    }

    /**
     * 根据用户名查询
     *
     * @param username 用户名
     * @return 查询的数据
     */
    @RequestMapping(value = "selectByUsername", produces = "text/application;charset=utf-8")
    @ResponseBody
    public String selectByUsername(String username) {
        User user = userService.selectByUsername(username);
        return JSON.toJSONString(user);
    }

    /**
     * 根据user primary key删除
     *
     * @param id user primary key
     * @return 删除状态
     */
    @RequestMapping("deleteById")
    @ResponseBody
    public String deleteById(Integer id) {
        int status = userService.deleteByPrimaryKey(id);
        UserPostKey userPostKey = new UserPostKey(id, null);
        userPostService.deleteByPrimaryKey(userPostKey);
        userRoleService.delete(id);
        JsonUtil jsonUtil = new JsonUtil();
        //设置状态
        Boolean restates = jsonUtil.getRestates(status);
        return JSON.toJSONString(restates);
    }

    /**
     * 修改
     *
     * @param id           user primary key
     * @param username     用户名
     * @param realName     姓名
     * @param departmentId 部门id
     * @return 修改状态
     */
    @RequestMapping("update")
    @ResponseBody
    public String update(Integer id, String username, String realName, Integer departmentId) {
        User user = new User(id, username, null, realName, String.valueOf(departmentId), null, null, null);
        int status = userService.updateByPrimaryKeySelective(user);
        userPostService.update(departmentId, id);
        JsonUtil jsonUtil = new JsonUtil();
        //设置状态
        Boolean restates = jsonUtil.getRestates(status);
        return JSON.toJSONString(restates);
    }

    //查询所有用户

    /**
     * 分页查询所有
     *
     * @param session 作用域
     * @param page    当前页
     * @param pageNum 每页条数
     * @return 页面
     */
    @RequestMapping("selectAll")
    public String selectAll(HttpSession session, Integer page, Integer pageNum,Integer status) {
        Integer count = userService.selectCount();
        List<User> users = userService.selectAll(page, pageNum);
        //分页方法
        Map<String, Integer> util = PageUtil.page(pageNum, page, count);
        Integer pages = util.get("page");
        Integer remaining_pages = util.get("remaining_pages");
        Integer counts = util.get("count");
        Map<String, Object> map = new HashMap<String, Object>();
        //存入分页数据
        map.put("num", remaining_pages);
        map.put("page", pages);
        map.put("count", counts);
        //存入map集合
        session.setAttribute("map", map);
        session.setAttribute("users", users);
        return StatusUtil.statusYe(status);
    }
}
